﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Linq.Expressions;
using MaymuseMS.DAL;
using MaymuseMS.Models;
using Zsnd.Helpers;

namespace MaymuseMS.DAO {
    public class DAO<TEntity> where TEntity : class, new() {

        private int _totalPages = 0;
        private int _totalRecords = 0;

        private int _pageIndex = 0;

        private IQueryable<TEntity> _query;
        private IEnumerable<TEntity> _enums;

        protected JQGridParm Parm { get; set; }
        protected Expression<Func<TEntity, bool>> Predicate { get; set; }
        protected GenericRepository<TEntity> GenericRepository { get; set; }

        protected int TotalPages {
            get {
                if (_totalPages == 0) {
                    _totalPages = (int)Math.Ceiling((float)TotalRecords / (float)Parm.Rows);
                }
                return _totalPages;
            }
        }
        protected int TotalRecords {
            get {
                if (_totalRecords == 0) {
                    _totalRecords = Query.Count();//先过滤再求总数
                }
                return _totalRecords;
            }
        }
        protected int PageIndex {
            get {
                if (_pageIndex == 0) {
                    _pageIndex = Convert.ToInt32(Parm.Page) - 1;
                }
                return _pageIndex;
            }
        }

        public IQueryable<TEntity> Query {
            get {
                if (_query == null) {
                    _query = GenericRepository.Get(Parm.Sidx, Parm.Sord, Parm.Filters, Predicate);
                }
                return _query;
            }
        }
        public IEnumerable<TEntity> Enums {
            get {
                if (_enums == null) {
                    _enums = GenericRepository.Get(PageIndex, Parm.Rows, Parm.Sidx, Parm.Sord, Parm.Filters);
                }
                return _enums;
            }
        }

        public DAO(JQGridParm parm, GenericRepository<TEntity> genericRepository, Expression<Func<TEntity, bool>> predicate) {
            Parm = parm;
            GenericRepository = genericRepository;
            Predicate = predicate;
        }
        public DAO(JQGridParm parm, GenericRepository<TEntity> genericRepository)
            : this(parm, genericRepository, null) {

        }
        //分页结果
        //public IEnumerable<TEntity> GetPaged() {
        //    return this.Enums;
        //}

        ////未分页
        //public IQueryable<TEntity> GetQuery() {
        //    return this.Query;
        //}
        //未分页求和
        public IEnumerable<int> GetSum(params Expression<Func<TEntity, int>>[] predicates) {
            if (predicates == null) throw new ArgumentNullException("predicates为空");
            int[] d = new int[predicates.Length];
            int i = 0;
            foreach (var p in predicates) {
                d[i++] = this.Query.Count() > 0 ? this.Query.Sum(p) : 0;
            }
            return d;
        }
        public IEnumerable<double> GetSum(params Expression<Func<TEntity, double>>[] predicates) {
            if (predicates == null) throw new ArgumentNullException("predicates为空");
            double[] d = new double[predicates.Length];
            int i = 0;
            foreach (var p in predicates) {
                d[i++] = this.Query.Count() > 0 ? this.Query.Sum(p) : 0;
            }
            return d;
        }
        public object GetData(object rows) {
            return GetData(rows, null);
        }

        public object GetData(object rows, object userdata) {
            if (rows == null) throw new ArgumentNullException("缺少rows");
            if (userdata == null) {
                return new {
                    success = true, total = this.TotalPages, page = Parm.Page,
                    records = this.TotalRecords, rows = rows
                };
            } else {
                return new {
                    success = true, total = this.TotalPages, page = Parm.Page,
                    records = this.TotalRecords, rows = rows, userdata = userdata
                };
            }
        }
    }
}